/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.ces4.produccion.jpa.controllers;

import co.com.ces4.produccion.jpa.controllers.exceptions.IllegalOrphanException;
import co.com.ces4.produccion.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.ces4.produccion.jpa.controllers.exceptions.PreexistingEntityException;
import co.com.ces4.produccion.jpa.entities.Usuario;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.ces4.produccion.jpa.entities.Perfil;
import java.util.ArrayList;
import java.util.List;
import co.com.ces4.produccion.jpa.entities.OrdenProduccion;
import co.com.ces4.produccion.jpa.entities.SolicitudProduccion;
import co.com.ces4.produccion.jpa.entities.Usuario_;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;

/**
 *
 * @author usuario
 */
public class UsuarioJpaController implements Serializable {

    public UsuarioJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) throws PreexistingEntityException, Exception {
        if (usuario.getPerfilList() == null) {
            usuario.setPerfilList(new ArrayList<Perfil>());
        }
        if (usuario.getOrdenProduccionList() == null) {
            usuario.setOrdenProduccionList(new ArrayList<OrdenProduccion>());
        }
        if (usuario.getSolicitudProduccionList() == null) {
            usuario.setSolicitudProduccionList(new ArrayList<SolicitudProduccion>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Perfil> attachedPerfilList = new ArrayList<Perfil>();
            for (Perfil perfilListPerfilToAttach : usuario.getPerfilList()) {
                perfilListPerfilToAttach = em.getReference(perfilListPerfilToAttach.getClass(), perfilListPerfilToAttach.getNmid());
                attachedPerfilList.add(perfilListPerfilToAttach);
            }
            usuario.setPerfilList(attachedPerfilList);
            List<OrdenProduccion> attachedOrdenProduccionList = new ArrayList<OrdenProduccion>();
            for (OrdenProduccion ordenProduccionListOrdenProduccionToAttach : usuario.getOrdenProduccionList()) {
                ordenProduccionListOrdenProduccionToAttach = em.getReference(ordenProduccionListOrdenProduccionToAttach.getClass(), ordenProduccionListOrdenProduccionToAttach.getOrdenProduccionPK());
                attachedOrdenProduccionList.add(ordenProduccionListOrdenProduccionToAttach);
            }
            usuario.setOrdenProduccionList(attachedOrdenProduccionList);
            List<SolicitudProduccion> attachedSolicitudProduccionList = new ArrayList<SolicitudProduccion>();
            for (SolicitudProduccion solicitudProduccionListSolicitudProduccionToAttach : usuario.getSolicitudProduccionList()) {
                solicitudProduccionListSolicitudProduccionToAttach = em.getReference(solicitudProduccionListSolicitudProduccionToAttach.getClass(), solicitudProduccionListSolicitudProduccionToAttach.getNmid());
                attachedSolicitudProduccionList.add(solicitudProduccionListSolicitudProduccionToAttach);
            }
            usuario.setSolicitudProduccionList(attachedSolicitudProduccionList);
            em.persist(usuario);
            for (Perfil perfilListPerfil : usuario.getPerfilList()) {
                perfilListPerfil.getUsuarioList().add(usuario);
                perfilListPerfil = em.merge(perfilListPerfil);
            }
            for (OrdenProduccion ordenProduccionListOrdenProduccion : usuario.getOrdenProduccionList()) {
                Usuario oldDsusuarioOfOrdenProduccionListOrdenProduccion = ordenProduccionListOrdenProduccion.getDsusuario();
                ordenProduccionListOrdenProduccion.setDsusuario(usuario);
                ordenProduccionListOrdenProduccion = em.merge(ordenProduccionListOrdenProduccion);
                if (oldDsusuarioOfOrdenProduccionListOrdenProduccion != null) {
                    oldDsusuarioOfOrdenProduccionListOrdenProduccion.getOrdenProduccionList().remove(ordenProduccionListOrdenProduccion);
                    oldDsusuarioOfOrdenProduccionListOrdenProduccion = em.merge(oldDsusuarioOfOrdenProduccionListOrdenProduccion);
                }
            }
            for (SolicitudProduccion solicitudProduccionListSolicitudProduccion : usuario.getSolicitudProduccionList()) {
                Usuario oldDsusuarioOfSolicitudProduccionListSolicitudProduccion = solicitudProduccionListSolicitudProduccion.getDsusuario();
                solicitudProduccionListSolicitudProduccion.setDsusuario(usuario);
                solicitudProduccionListSolicitudProduccion = em.merge(solicitudProduccionListSolicitudProduccion);
                if (oldDsusuarioOfSolicitudProduccionListSolicitudProduccion != null) {
                    oldDsusuarioOfSolicitudProduccionListSolicitudProduccion.getSolicitudProduccionList().remove(solicitudProduccionListSolicitudProduccion);
                    oldDsusuarioOfSolicitudProduccionListSolicitudProduccion = em.merge(oldDsusuarioOfSolicitudProduccionListSolicitudProduccion);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findUsuario(usuario.getDsid()) != null) {
                throw new PreexistingEntityException("Usuario " + usuario + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getDsid());
            List<Perfil> perfilListOld = persistentUsuario.getPerfilList();
            List<Perfil> perfilListNew = usuario.getPerfilList();
            List<OrdenProduccion> ordenProduccionListOld = persistentUsuario.getOrdenProduccionList();
            List<OrdenProduccion> ordenProduccionListNew = usuario.getOrdenProduccionList();
            List<SolicitudProduccion> solicitudProduccionListOld = persistentUsuario.getSolicitudProduccionList();
            List<SolicitudProduccion> solicitudProduccionListNew = usuario.getSolicitudProduccionList();
            List<String> illegalOrphanMessages = null;
            for (OrdenProduccion ordenProduccionListOldOrdenProduccion : ordenProduccionListOld) {
                if (!ordenProduccionListNew.contains(ordenProduccionListOldOrdenProduccion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain OrdenProduccion " + ordenProduccionListOldOrdenProduccion + " since its dsusuario field is not nullable.");
                }
            }
            for (SolicitudProduccion solicitudProduccionListOldSolicitudProduccion : solicitudProduccionListOld) {
                if (!solicitudProduccionListNew.contains(solicitudProduccionListOldSolicitudProduccion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain SolicitudProduccion " + solicitudProduccionListOldSolicitudProduccion + " since its dsusuario field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Perfil> attachedPerfilListNew = new ArrayList<Perfil>();
            for (Perfil perfilListNewPerfilToAttach : perfilListNew) {
                perfilListNewPerfilToAttach = em.getReference(perfilListNewPerfilToAttach.getClass(), perfilListNewPerfilToAttach.getNmid());
                attachedPerfilListNew.add(perfilListNewPerfilToAttach);
            }
            perfilListNew = attachedPerfilListNew;
            usuario.setPerfilList(perfilListNew);
            List<OrdenProduccion> attachedOrdenProduccionListNew = new ArrayList<OrdenProduccion>();
            for (OrdenProduccion ordenProduccionListNewOrdenProduccionToAttach : ordenProduccionListNew) {
                ordenProduccionListNewOrdenProduccionToAttach = em.getReference(ordenProduccionListNewOrdenProduccionToAttach.getClass(), ordenProduccionListNewOrdenProduccionToAttach.getOrdenProduccionPK());
                attachedOrdenProduccionListNew.add(ordenProduccionListNewOrdenProduccionToAttach);
            }
            ordenProduccionListNew = attachedOrdenProduccionListNew;
            usuario.setOrdenProduccionList(ordenProduccionListNew);
            List<SolicitudProduccion> attachedSolicitudProduccionListNew = new ArrayList<SolicitudProduccion>();
            for (SolicitudProduccion solicitudProduccionListNewSolicitudProduccionToAttach : solicitudProduccionListNew) {
                solicitudProduccionListNewSolicitudProduccionToAttach = em.getReference(solicitudProduccionListNewSolicitudProduccionToAttach.getClass(), solicitudProduccionListNewSolicitudProduccionToAttach.getNmid());
                attachedSolicitudProduccionListNew.add(solicitudProduccionListNewSolicitudProduccionToAttach);
            }
            solicitudProduccionListNew = attachedSolicitudProduccionListNew;
            usuario.setSolicitudProduccionList(solicitudProduccionListNew);
            usuario = em.merge(usuario);
            for (Perfil perfilListOldPerfil : perfilListOld) {
                if (!perfilListNew.contains(perfilListOldPerfil)) {
                    perfilListOldPerfil.getUsuarioList().remove(usuario);
                    perfilListOldPerfil = em.merge(perfilListOldPerfil);
                }
            }
            for (Perfil perfilListNewPerfil : perfilListNew) {
                if (!perfilListOld.contains(perfilListNewPerfil)) {
                    perfilListNewPerfil.getUsuarioList().add(usuario);
                    perfilListNewPerfil = em.merge(perfilListNewPerfil);
                }
            }
            for (OrdenProduccion ordenProduccionListNewOrdenProduccion : ordenProduccionListNew) {
                if (!ordenProduccionListOld.contains(ordenProduccionListNewOrdenProduccion)) {
                    Usuario oldDsusuarioOfOrdenProduccionListNewOrdenProduccion = ordenProduccionListNewOrdenProduccion.getDsusuario();
                    ordenProduccionListNewOrdenProduccion.setDsusuario(usuario);
                    ordenProduccionListNewOrdenProduccion = em.merge(ordenProduccionListNewOrdenProduccion);
                    if (oldDsusuarioOfOrdenProduccionListNewOrdenProduccion != null && !oldDsusuarioOfOrdenProduccionListNewOrdenProduccion.equals(usuario)) {
                        oldDsusuarioOfOrdenProduccionListNewOrdenProduccion.getOrdenProduccionList().remove(ordenProduccionListNewOrdenProduccion);
                        oldDsusuarioOfOrdenProduccionListNewOrdenProduccion = em.merge(oldDsusuarioOfOrdenProduccionListNewOrdenProduccion);
                    }
                }
            }
            for (SolicitudProduccion solicitudProduccionListNewSolicitudProduccion : solicitudProduccionListNew) {
                if (!solicitudProduccionListOld.contains(solicitudProduccionListNewSolicitudProduccion)) {
                    Usuario oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion = solicitudProduccionListNewSolicitudProduccion.getDsusuario();
                    solicitudProduccionListNewSolicitudProduccion.setDsusuario(usuario);
                    solicitudProduccionListNewSolicitudProduccion = em.merge(solicitudProduccionListNewSolicitudProduccion);
                    if (oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion != null && !oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion.equals(usuario)) {
                        oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion.getSolicitudProduccionList().remove(solicitudProduccionListNewSolicitudProduccion);
                        oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion = em.merge(oldDsusuarioOfSolicitudProduccionListNewSolicitudProduccion);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = usuario.getDsid();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getDsid();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<OrdenProduccion> ordenProduccionListOrphanCheck = usuario.getOrdenProduccionList();
            for (OrdenProduccion ordenProduccionListOrphanCheckOrdenProduccion : ordenProduccionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the OrdenProduccion " + ordenProduccionListOrphanCheckOrdenProduccion + " in its ordenProduccionList field has a non-nullable dsusuario field.");
            }
            List<SolicitudProduccion> solicitudProduccionListOrphanCheck = usuario.getSolicitudProduccionList();
            for (SolicitudProduccion solicitudProduccionListOrphanCheckSolicitudProduccion : solicitudProduccionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the SolicitudProduccion " + solicitudProduccionListOrphanCheckSolicitudProduccion + " in its solicitudProduccionList field has a non-nullable dsusuario field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Perfil> perfilList = usuario.getPerfilList();
            for (Perfil perfilListPerfil : perfilList) {
                perfilListPerfil.getUsuarioList().remove(usuario);
                perfilListPerfil = em.merge(perfilListPerfil);
            }
            em.remove(usuario);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

    public List<Usuario> getUsuarioList(String id, String nombre, String login, Boolean activo) {
        EntityManager em = getEntityManager();
        StringBuilder sb = new StringBuilder("SELECT user FROM Usuario user WHERE 1=1 ");
        if (id != null) {
            sb.append("AND (user.dsid = :DSID ");
            if (nombre != null) {
                sb.append("AND user.dsnombre LIKE :DSNOMBRE ");
            }
            if (login != null) {
                sb.append("AND user.dsusuario LIKE :DSUSUARIO ");
            }
            if (activo != null) {
                sb.append("AND user.snestado = :ESTADO");
            }
            sb.append(")");
        } else if (nombre != null) {
            sb.append("AND (user.dsnombre LIKE :DSNOMBRE ");
            if (login != null) {
                sb.append("AND user.dsusuario LIKE :DSUSUARIO ");
            }
            if (activo != null) {
                sb.append("AND user.snestado = :ESTADO");
            }
            sb.append(")");
        } else if (login != null) {
            sb.append("AND (user.dsusuario LIKE :DSUSUARIO ");
            if (activo != null) {
                sb.append("AND user.snestado = :ESTADO");
            }
            sb.append(")");
        } else if (activo != null) {
            sb.append("AND user.snestado = :ESTADO");
        }

        Query p = em.createQuery(sb.toString());
        if (id != null) {
            p.setParameter("DSID", id);
        }
        if (nombre != null) {
            p.setParameter("DSNOMBRE", "%" + nombre + "%");
        }
        if (login != null) {
            p.setParameter("DSUSUARIO", "%" + login + "%");
        }
        if (activo != null) {
            if (activo) {
                p.setParameter("ESTADO", true);
            } else {
                p.setParameter("ESTADO", false);
            }

        }
        List<Usuario> usuarios = p.getResultList();
        return usuarios;
    }

    public Usuario validateUser(String user, String password) {
        EntityManager em = getEntityManager();
        try {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Usuario> cq = cb.createQuery(Usuario.class);
            Root<Usuario> userR = cq.from(Usuario.class);
            cq.select(userR);

            if (user == null || user.equals("") || password == null || password.equals("")) {
                return null;
            }
            cq.where(cb.equal(userR.get(Usuario_.dsusuario), user), cb.and(cb.equal(userR.get(Usuario_.dspassword), password)));
            Query q = em.createQuery(cq);
            try {
                return (Usuario) q.getSingleResult();

            } catch (NoResultException e) {
                return null;
            }
        } finally {
            em.close();
        }
    }
}
